package cn.zn.dict.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.zn.base.common.constant.Constants;
import cn.zn.base.exception.CustomException;
import cn.zn.redis.service.RedisService;
import cn.zn.dict.entity.SysDictType;
import cn.zn.dict.entity.SysDictValue;
import cn.zn.dict.mapper.SysDictTypeMapper;
import cn.zn.dict.mapper.SysDictValueMapper;
import cn.zn.dict.service.SysDictTypeService;
import cn.zn.dict.vo.SysDictTypeEditVo;
import cn.zn.dict.vo.SysDictTypePageVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Collection;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zn-admin
 * @since 2021-01-28
 */
@Service
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements SysDictTypeService {

    @Autowired
    private RedisService redisService;

    @Autowired
    private SysDictValueMapper dictValueMapper;

    /**
     * 根据条件分页查询字典类型
     *
     * @param vo 字典类型信息
     * @return 字典类型集合信息
     */
    @Override
    public Object selectDictTypeList(SysDictTypePageVo vo) {
        if (!vo.getPage()) {
            return baseMapper.selectDictTypeList(vo);
        }

        Page<SysDictType> page = new Page<>(vo.getCurrent(), vo.getSize());
        return baseMapper.selectDictTypeList(page, vo);
    }

    @Override
    @Transactional
    public void insertDictType(SysDictTypeEditVo vo) {
        if (checkDictTypeUnique(vo.getDictType(), null)) {
            throw new CustomException("新增字典'" + vo.getDictName() + "'失败，字典类型已存在");
        }

        SysDictType sysDictType = new SysDictType();
        BeanUtil.copyProperties(vo, sysDictType);
        boolean success = sysDictType.insert();
        if (success) {
            clearDictCache();
        }

    }

    @Override
    @Transactional
    public void updateDictType(String id, SysDictTypeEditVo vo) {
        if (checkDictTypeUnique(vo.getDictType(), id)) {
            throw new CustomException("修改字典'" + vo.getDictName() + "'失败，字典类型已存在");
        }

        SysDictType sysDictType = new SysDictType();
        BeanUtil.copyProperties(vo, sysDictType);
        sysDictType.setId(id);
        boolean success = sysDictType.updateById();
        if (success) {
            clearDictCache();
        }
    }

    @Override
    @Transactional
    public void deleteDictTypeByIds(String[] dictIds) {
        for (String dictId : dictIds) {
            SysDictType sysDictType = baseMapper.selectById(dictId);
            if (sysDictType == null) {
                continue;
            }

            QueryWrapper<SysDictValue> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("dict_type", sysDictType.getDictType());
            int count = dictValueMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new CustomException(String.format("%1$s已分配,不能删除", sysDictType.getDictName()));
            }
        }
        baseMapper.deleteBatchIds(Arrays.asList(dictIds));
        clearDictCache();
    }

    @Override
    public void clearDictCache() {
        Collection<String> keys = redisService.keys(Constants.SYS_DICT_KEY + "*");
        redisService.deleteObject(keys);
    }

    /**
     * 校验字典类型称是否唯一
     *
     * @param dictType 字典类型
     * @return 结果
     */
    private Boolean checkDictTypeUnique(String dictType, String id) {
        QueryWrapper<SysDictType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dict_type", dictType);
        if (StrUtil.isNotBlank(id)) {
            queryWrapper.ne("id", id);
        }
        int count = baseMapper.selectCount(queryWrapper);
        return count > 0;
    }

}
